package com.lynn.common.net.exception

import androidx.core.net.ParseException
import com.google.gson.JsonParseException
import org.apache.http.conn.ConnectTimeoutException
import org.json.JSONException
import retrofit2.HttpException
import java.net.ConnectException
import java.net.SocketTimeoutException
import javax.net.ssl.SSLHandshakeException

/**
 * @description: 异常处理
 * @author: bailing
 * @datetime: 2025/5/27 13:39
 **/
object ExceptionHandle {
    //未授权
    private const val UNAUTHORIZED: Int = 401

    //禁止的
    private const val FORBIDDEN: Int = 403

    //未找到
    private const val NOT_FOUND: Int = 404

    //请求超时
    private const val REQUEST_TIMEOUT: Int = 408

    //内部服务器错误
    private const val INTERNAL_SERVER_ERROR: Int = 500

    //错误网关
    private const val BAD_GATEWAY: Int = 502

    //暂停服务
    private const val SERVICE_UNAVAILABLE: Int = 503

    //网关超时
    private const val GATEWAY_TIMEOUT: Int = 504


    fun handleException(t: Throwable): ResponseThrowable {
        var responseThrowable: ResponseThrowable? = null
        when (t) {
            is HttpException -> {
                responseThrowable = ResponseThrowable(t, ErrorCode.HTTP_ERROR)
                responseThrowable.msg = handleHttpException(t.code())
            }

            is ServerException -> {
                responseThrowable = ResponseThrowable(t, t.code)
                responseThrowable.msg = t.message
            }

            is JsonParseException, is JSONException, is ParseException -> {
                responseThrowable = ResponseThrowable(t, ErrorCode.PARSE_ERROR)
                responseThrowable.msg = "解析错误"
            }

            is ConnectException -> {
                responseThrowable = ResponseThrowable(t, ErrorCode.NETWORK_ERROR)
                responseThrowable.msg = "连接失败"
            }

            is SSLHandshakeException -> {
                responseThrowable = ResponseThrowable(t, ErrorCode.SSL_ERROR)
                responseThrowable.msg = "证书验证失败"
            }

            is ConnectTimeoutException -> {
                responseThrowable = ResponseThrowable(t, ErrorCode.TIMEOUT_ERROR)
                responseThrowable.msg = "连接超时"
            }

            is SocketTimeoutException -> {
                responseThrowable = ResponseThrowable(t, ErrorCode.TIMEOUT_ERROR)
                responseThrowable.msg = "连接超时"
            }

            else -> {
                responseThrowable = ResponseThrowable(t, ErrorCode.UNKNOWN)
                responseThrowable.msg = "未知错误"
            }

        }
        return responseThrowable
    }

    private fun handleServerException(code: Int): String {
        return when (code) {
            UNAUTHORIZED -> "未授权"
            FORBIDDEN -> "禁止访问"
            NOT_FOUND -> "未找到"
            REQUEST_TIMEOUT -> "请求超时"
            GATEWAY_TIMEOUT -> "网关超时"
            INTERNAL_SERVER_ERROR -> "内部服务器错误"
            BAD_GATEWAY -> "错误网关"
            SERVICE_UNAVAILABLE -> "暂停服务"
            else -> "网络错误"
        }
    }

    private fun handleHttpException(code: Int): String {
        return when (code) {
            UNAUTHORIZED -> "未授权"
            FORBIDDEN -> "禁止访问"
            NOT_FOUND -> "未找到"
            REQUEST_TIMEOUT -> "请求超时"
            GATEWAY_TIMEOUT -> "网关超时"
            INTERNAL_SERVER_ERROR -> "内部服务器错误"
            BAD_GATEWAY -> "错误网关"
            SERVICE_UNAVAILABLE -> "暂停服务"
            else -> "网络错误"
        }
    }

}

/**
 * @description: 自定义异常类
 * @author: bailing
 * @datetime: 2025/5/27 13:43
 **/
class ResponseThrowable(
    private val t: Throwable?,
    private val code: Int?
) : Exception(t) {
    var msg: String? = null
}

class ServerException constructor() : RuntimeException() {
    var code: Int? = null
    var msg: String? = null

    constructor(code: Int?, msg: String?) : this() {

        this.code = code
        this.msg = msg
    }
}

/**
 * @description: 约定异常码
 * @author: bailing
 * @datetime: 2025/5/27 13:43
 **/
object ErrorCode {
    // 未知错误
    const val UNKNOWN: Int = 1000

    // 解析错误
    const val PARSE_ERROR: Int = 1001

    // 网络错误
    const val NETWORK_ERROR: Int = 1002

    // 协议出错
    const val HTTP_ERROR: Int = 1003

    // 证书出错
    const val SSL_ERROR: Int = 1005

    // 连接超时
    const val TIMEOUT_ERROR: Int = 1006
}
